process.title = 'WebRTC Signaling Server';

import * as http from 'http';
// import * as path from 'path';
import express from 'express';
// import { Server, ServerOptions, Socket } from 'socket.io';
import { Server, ServerOptions } from 'socket.io';
// import { getLogger, configure } from 'log4js';

// import { RoomType } from './lib/Room';
// import { Peer } from './lib/Peer';
// import { lConfig } from './config/config';
import runWebSocketServer from './socket';
import runHttpsServer from './httpServer';
import { IMembers } from './lib/Member'
import { Rooms } from './lib/Rooms'

// configure(path.join(path.resolve(), '/log4js.json'));
// const logger = getLogger('Server');
const helmet = require('helmet');
const cors = require('cors');
const bodyParser = require('body-parser');
const compression = require('compression');
const morgan = require('morgan');
// const kurentoClient = require('./kurentoClient');

const app = express();
app.use(compression());

app.use(morgan('dev'));

app.use(helmet.hsts());
app.use(bodyParser.json({limit: '25mb'}));
app.use(bodyParser.urlencoded({ extended: true, limit: '25mb' }));
app.use(cors());

app.locals.members = <IMembers>{};
app.locals.rooms = <Rooms>{};
app.locals.sockets = <any>{};

async function run() {
    const serverOption: Partial<ServerOptions> = {
        // pingTimeout: 3000,
        // pingInterval: 5000,
        transports: ['websocket'],
        allowUpgrades: false,
    };

    let httpsServer: http.Server = await runHttpsServer(app);
    app.locals.io = new Server(httpsServer, serverOption);
    app.locals.io.path('/intercom/');
    // const kurento = new kurentoClient();

    // Run WebSocket server.
    // await runWebSocketServer(io, kurento);
    await runWebSocketServer(app);

    console.log('socket.io');

    // Log rooms status
    /*setInterval(() => {
        let all =0;
        let closed = 0;

        rooms.forEach(room=>{
            all++;
            if (room.closed) {
                closed++;
            }

            // 检查 废弃的次数
            room.checkDeserted();
            logger.debug(JSON.stringify(room.statusReport()));
        });

        logger.info('Room total: %s, closed: %s', all, closed);
    }, lConfig.roomStatusInterval * 1000);*/
}

/*const runWebSocketServer = async () => {

    logger.info('Run websocket server...');

    io.on('connection', async (socket: Socket) => {
        const { roomId, peerId } = socket.handshake.query;

        if (!roomId || !peerId) {
            logger.warn('Connection request without room id and/or peer id.');
            socket.disconnect(true);
            return;
        }

        logger.info('Connection request [roomId: %s, peerId: %s]', roomId, peerId);

        try {
            const room: Room = await getOrCreateRoom(roomId as string) as Room;
            let peer: Peer = room.getPeer(peerId as string) as Peer;

            if (!peer) {
                peer = new Peer(peerId as string, socket, room);
                room.handlePeer(peer);
                logger.info('New peer, %s, %s', peerId, socket.id);
            } else {
                peer.handlePeerReconnect(socket);
                logger.info('Peer reconnect, %s, %s', peerId, socket.id);
            }
        } catch (error) {
            logger.error('Room creation or room joining failed [error: "%o"]', error);
            socket.disconnect(true);
            return;
        }
    });
};*/

/*const getOrCreateRoom = async (roomId: string) => {
    let room = rooms.get(roomId);
    if (room) return room;

    logger.info('Creating a new room [roomId: "%s"]', roomId);

    try {
        // Connect Kurento Media Server.
        const client = await kurento.getClient();
        logger.info('Creating a new room [roomId: "%s"]', client);

        room = await Room.create(client, roomId);

        const pipeline = client.createMediaPipeline();

        console.log(pipeline);

        rooms.set(roomId, room);
        room.on('close', () => rooms.delete(roomId));
    } catch (error) {
        console.error(error)
    }

    return room
};*/

run();
